package com.lht.testDemo;

import org.junit.Test;
import sun.misc.Contended;

/**
 * @author Eric
 * @version 1.0
 * @date 2019-11-11
 */
public class FalseSharing {

    @Test
    public void test1() throws InterruptedException {
        test(new ShareOne());
    }

    @Test
    public void test2() throws InterruptedException {
        testTwo(new ShareTwo());
    }

    @Test
    public void test3() throws InterruptedException {
        testThreee(new ShareThree());
    }

    public static void test(ShareOne one) throws InterruptedException {
        long start = System.currentTimeMillis();

        Thread tOne = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100000000; i++) {
                    one.x++;
                }
            }
        });

        Thread tTwo = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100000000; i++) {
                    one.y++;
                }
            }
        });
        tOne.start();
        tTwo.start();
        tOne.join();
        tTwo.join();
        System.out.println(System.currentTimeMillis() - start);
        System.out.println(one);
    }

    public static void testTwo(ShareTwo one) throws InterruptedException {
        long start = System.currentTimeMillis();

        Thread tOne = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100000000; i++) {
                    one.x++;
                }
            }
        });

        Thread tTwo = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100000000; i++) {
                    one.y++;
                }
            }
        });
        tOne.start();
        tTwo.start();
        tOne.join();
        tTwo.join();
        System.out.println(System.currentTimeMillis() - start);
        System.out.println(one);
    }

    public static void testThreee(ShareThree one) throws InterruptedException {
        long start = System.currentTimeMillis();

        Thread tOne = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100000000; i++) {
                    one.x++;
                }
            }
        });

        Thread tTwo = new Thread(new Runnable() {
            @Override
            public void run() {
                for (int i = 0; i < 100000000; i++) {
                    one.y++;
                }
            }
        });
        tOne.start();
        tTwo.start();
        tOne.join();
        tTwo.join();
        System.out.println(System.currentTimeMillis() - start);
        System.out.println(one);
    }

    public static class ShareOne {
        public volatile long x;
        public volatile long y;

    }

    /**
     * 解决方法1
     */
    public static class ShareTwo {

        public volatile long x;
        public volatile long a, b, c, d, e, f, g;
        public volatile long y;
    }

    /**
     * 需要添加 jvm参数  -XX:-RestrictContended
     * 启动的时候 要加参数
     */
    public static class ShareThree {
        @Contended
        public volatile long x;
        /**
         * 加类上面，只会有一个字段生效？待确认
         */
        @Contended
        public volatile long y;
    }
}
